package edu.buaa.act.travel.m.tpdl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONObject;

public abstract class Activity implements Serializable, JSONable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	String id;
	
	Map<String, Flow> outgoing  = new HashMap<String, Flow>();
	Map<String, Flow> incoming = new HashMap<String, Flow>();
	
	protected Activity initial = null;
	protected List<Activity> subactivities = null;
	protected Activity parent = null;
	
	private TripItinerary itinerary = null;
	
	Flow defaultOutgoing = null;
	
	public Flow createOutFlow(String name){
		Flow flow = new Flow(name, this);
		outgoing.put(name, flow);
		if(defaultOutgoing == null){
			defaultOutgoing = flow;
		}
		return flow;
	}
	
	public void addIncomingFlow(Flow flow){
		incoming.put(flow.getId(), flow);
		flow.setTarget(this);
	}
	
	public Flow addOutgoingFlow(Flow flow){
		if(!outgoing.containsValue(flow)){
			if(this.defaultOutgoing==null){
				defaultOutgoing = flow;
			}
			outgoing.put(flow.getId(), flow);
			flow.setSource(this);			
		}
		return flow;
	}

	public Activity addSubActivity(Activity a){
		if(subactivities == null){
			subactivities = new ArrayList<Activity>();
		}
		if(a instanceof StartActivity){
			if(initial == null){
				initial = a;
			}
		}
		subactivities.add(a);
		a.setItinerary(getItinerary());
		a.setParent(this);
		return this;
	}
	
	protected abstract JSONObject toJSONObject();
	
	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public Flow getDefaultOutgoing() {
		return defaultOutgoing;
	}

	public void setDefaultOutgoing(Flow defaultOutgoing) {
		this.defaultOutgoing = defaultOutgoing;
	}

	public Activity getInitial() {
		return initial;
	}

	public void setInitial(Activity initial) {
		this.initial = initial;
	}

	public List<Activity> getSubactivities() {
		if(subactivities == null){
			subactivities = new ArrayList<Activity>();
		}
		return subactivities;
	}

	public void setSubactivities(List<Activity> subactivities) {
		this.subactivities = subactivities;
	}

	public Activity getParent() {
		return parent;
	}

	public void setParent(Activity parent) {
		this.parent = parent;
	}

	public TripItinerary getItinerary() {
		return itinerary;
	}

	public void setItinerary(TripItinerary itinerary) {
		this.itinerary = itinerary;
	}
}
